;; The idea for this macro is taken from:
;; https://spritely.institute/static/papers/scheme-primer.html#fn.19

;; We want to achieve a syntax like the following:

;; (for ((i 0) (< i 10) (+ i 2))
;;   (display (string-append "i is: " (number->string i) "\n")))

;; OK, GO!

(import
 (except (rnrs base) let-values)
 (only (guile)
       lambda* λ))


(define-syntax for
  (syntax-rules ()
    [(_ ((counter-var counter-init) condition counter-update)
        expr* ...)
     (let loop ([counter-var counter-init])
       (cond
        ;; Stop iterating, if the condition is no longer
        ;; true.
        [(not condition)
         ;; Nothing left to do, return the counter value.
         counter-var]
        ;; Do an interation. Run all body expressions and
        ;; then do a recursive call updating the counter.
        [else
         expr* ...
         (loop counter-update)]))]))


(for ((i 0) (< i 10) (+ i 2))
  (display (string-append "i is: " (number->string i) "\n")))
